package com.foton.lotterydomain.strategy.service.draw.impl;

import com.foton.lotterydomain.strategy.model.aggregates.StrategyRich;
import com.foton.lotterydomain.strategy.model.req.DrawReq;
import com.foton.lotterydomain.strategy.model.res.DrawResult;
import com.foton.lotterydomain.strategy.repository.IStrategyRepository;
import com.foton.lotterydomain.strategy.service.algorithm.IDrawAlgorithm;
import com.foton.lotterydomain.strategy.service.draw.AbstractDrawBase;
//import com.foton.lotterydomain.strategy.service.draw.DrawBase;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author RenPu
 * @Date 2023/11/24 9:52
 * @Version 1.0
 * @Description: 抽奖业务实现层
 **/
@Service
public class DrawExecImpl extends AbstractDrawBase {


    /**
     * 获取不在抽奖范围内的列表，包括：奖品库存为空、风控策略、临时调整等，这类数据是含有业务逻辑的，
     * 所以需要由具体的实现方决定
     *
     * @param strategyId 策略ID
     * @return 排除的奖品ID集合
     */
    @Override
    protected List<String> queryExcludeAwardIds(Long strategyId) {
        return strategyRepository.queryNoStockStrategyAwardList(strategyId);
    }


    /**
     * 根据抽奖算法的计算，获取对应的商品ID值
     *
     * @param strategyId
     * @param drawAlgorithm
     * @param excludeAwardIds
     * @return
     */
    @Override
    protected String drawAlgorithm(Long strategyId, IDrawAlgorithm drawAlgorithm, List<String> excludeAwardIds) {

        String awardId = drawAlgorithm.randomDraw(strategyId, excludeAwardIds);

        if (null == awardId) {
            return null;
        }

        /*
         * 扣减库存，暂时采用数据库行级锁的方式进行扣减库存，后续优化为 Redis 分布式锁扣减 decr/incr
         * 注意：通常数据库直接锁行记录的方式并不能支撑较大体量的并发，但此种方式需要了解，因为在分库分表下的正常数据流量下的个人数据记录中，是可以使用行级锁的，因为他只影响到自己的记录，不会影响到其他人
         */
        //针对策略详情的，商品数量进行扣减
        boolean result = strategyRepository.deductStock(strategyId, awardId);


        return result ? awardId : null;
    }


}
